package com.bao.demo.utils;

import com.bao.demo.jdbcdemo01.User;
import com.bao.demo.work.flower.entity.Flower;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * @author baoye
 * @date 2024-08-23/13:49
 */
public final class BaseDAO {
    private BaseDAO() {
    }

    public static int insertOne(String sql, Object... o) {
        return sqlDML(sql, o);
    }

    public static int deleteAll(String sql, Object... o) {
        if (!sql.startsWith("delete from")) {
            try {
                throw new Exception("不是delete语句");
            } catch (Exception e) {
                System.out.println("\u001B[33m" + e.getMessage() + "\u001B[0m");
                return 0;
            }
        }
        return sqlDML(sql, o);

    }

    public static int deleteAll(String sql, Integer[] ids) {
        try {
            if (sql == null || sql.trim().length() == 0) {
                throw new IllegalArgumentException("非法参数");
            }
        } catch (IllegalArgumentException ie) {
            System.out.println("\u001B[33m" + ie.getMessage() + "\u001B[0m");
            return 0;
        }
        if (!sql.startsWith("delete from")) {
            try {
                throw new Exception("不是delete语句");
            } catch (Exception e) {
                System.out.println("\u001B[33m" + e.getMessage() + "\u001B[0m");
                return 0;
            }
        }
        if (ids.length == 0) {
            try {
                throw new Exception("空数组");
            } catch (Exception e) {
                System.out.println("\u001B[33m" + e.getMessage() + "\u001B[0m");
                return 0;
            }
        }
        int col = 0;
        Connection connection = JDBCUtils.getConnection();

        PreparedStatement ps = null;

        try {
            assert connection != null;
            ps = connection.prepareStatement(sql);

            connection.setAutoCommit(false);

            for (Integer id : ids) {
                ps.setObject(1, id);
                ps.addBatch();
            }
            int[] ints = ps.executeBatch();

            for (int anInt : ints) {
                if (anInt == 1) {
                    col++;
                } else {
                    throw new SQLException("出现删除失败记录");
                }
            }
            connection.commit();
        } catch (SQLException e) {
            try {
                connection.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            JDBCUtils.close(ps, connection);
        }
        return col;
    }

    public static int deleteOne(String sql, Object... o) {
        if (!sql.endsWith("limit 1")) {
            return deleteAll(sql + " limit 1", o);
        } else {
            return deleteAll(sql, o);
        }
    }

    public static int update(String sql, Object... o) {
        if (!sql.startsWith("update")) {
            try {
                throw new Exception("不是修改语句");
            } catch (Exception e) {
                System.out.println("\u001B[33m" + e.getMessage() + "\u001B[0m");
                return 0;
            }
        }
        return sqlDML(sql, o);

    }


    /**
     * @param sql sql语句
     * @param o   任意数量的参数
     * @return 1
     */
    private static int sqlDML(String sql, Object... o) {
        try {
            if (sql == null || sql.trim().length() == 0) {
                throw new IllegalArgumentException("非法参数");
            }
        } catch (IllegalArgumentException ie) {
            ie.printStackTrace();
        }

        int col = 0;
        Connection connection = JDBCUtils.getConnection();
        assert connection != null;
        PreparedStatement statement = JDBCUtils.createStatement(connection, sql, o);
        try {
            assert statement != null;
            col = statement.executeUpdate();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCUtils.close(statement, connection);
        }
        return col;
    }

    public static <T> List<T> selectMul(String sql, Class<T> c, Object... params) {
        if (sql == null || sql.trim().length() == 0 || params == null) {
            throw new IllegalArgumentException("非法参数");
        }
        List<T> list = new ArrayList<>();
        Connection connection = JDBCUtils.getConnection();
        PreparedStatement statement = JDBCUtils.createStatement(connection, sql, params);
        ResultSet res = JDBCUtils.getRes(statement);
        try {
            Constructor<T> declaredConstructor = c.getDeclaredConstructor();


            ResultSetMetaData metaData = res.getMetaData();//标题

            int colCount = metaData.getColumnCount();

            while (res.next()) {
                T t = declaredConstructor.newInstance();
                for (int i = 1; i < colCount + 1; i++) {
                    String columnName = metaData.getColumnName(i);

                    Object columnValue = res.getObject(i);

                    Field declaredField = c.getDeclaredField(columnName);

                    declaredField.setAccessible(true);

                    declaredField.set(t, columnValue);

                }
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(res, statement, connection);
        }
        return null;
    }

    public static <T> T selectOne(String sql, Class<T> c, Integer id) {
        if (sql == null || sql.trim().length() == 0 || id == null || id <= 0) {
            throw new IllegalArgumentException("非法参数");
        }
        Connection connection = JDBCUtils.getConnection();
        assert connection != null;
        PreparedStatement statement = JDBCUtils.createStatement(connection, sql, id);
        ResultSet res = JDBCUtils.getRes(statement);
        try {
            Constructor<T> declaredConstructor = c.getDeclaredConstructor();
            T t = declaredConstructor.newInstance();

            assert res != null;
            ResultSetMetaData metaData = res.getMetaData();//标题

            int colCount = metaData.getColumnCount();

            res.next();

            for (int i = 1; i < colCount + 1; i++) {
                String columnName = metaData.getColumnName(i);

                Object columnValue = null;
                try {
                    columnValue = res.getObject(i);
                } catch (SQLException throwables) {
                    return null;
                }

                Field declaredField = c.getDeclaredField(columnName);

                declaredField.setAccessible(true);


                declaredField.set(t, columnValue);

            }
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(res, statement, connection);
        }
        return null;
    }


}
